package com.twang.stock.task.old;

import com.alibaba.fastjson.JSONObject;
import com.twang.stock.entity.CompanyCodeInfo;
import com.twang.stock.entity.GaiNianZiJingPaiHang;
import com.twang.stock.entity.HotTag;
import com.twang.stock.entity.StockInfo;
import com.twang.stock.mapper.GaiNianZiJingPaiHangMapper;
import com.twang.stock.common.CommonUtils;
import com.twang.stock.enmu.GaiNianEnum;
import com.twang.stock.service.jinyan.CompanyCodeInfoService;
import com.twang.stock.service.jinyan.HolidayService;
import com.twang.stock.service.jinyan.HotTagService;
import com.twang.stock.email.SendmailService;
import org.assertj.core.util.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @param ：
 * 每日14：57更新
 * 即时--http://data.10jqka.com.cn/funds/gnzjl/ajax/1/free/1/
 *             3日：http://data.10jqka.com.cn/funds/gnzjl/board/3/ajax/1/free/1/
 *             5日：http://data.10jqka.com.cn/funds/gnzjl/board/5/ajax/1/free/1/
 *           明细：http://q.10jqka.com.cn/gn/detail/code/300845/
 */
@Slf4j
@Service
public class GaiNianZiJingPaiHangTask  extends BaseTask{

    public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36";
    public static String COOKIE = "v=A3mH6ooqPRK0e-GGeAjFux6xiO5Qhm04V3qRzJuu9aAfIpcY49Z9COfKoZ0o";
    @Resource
    private GaiNianZiJingPaiHangMapper gaiNianZiJingPaiHangMapper;

    @Autowired
    private HotTagService hotTagService;

    @Autowired
    private CompanyCodeInfoService companyCodeInfoService;

   public static Pattern regex = Pattern.compile("<span class=\"page_info\">(.*)</span>");
    /** 热度表*/
    private static Long hot_tag_id=new Long(0);

    private static Integer HOT_TAG_NUM=1;

    @Autowired
    private SendmailService sendmailService;

    @Autowired
    private QinXuGaoDuTask qinXuGaoDuTask;

    @Autowired
    private HolidayService holidayService;

  //  @Scheduled(cron = "0 15 15 * * ?")
    public void excute() {
        try {
            if (!isWork()) {
                return;
            }
            updateHistortData(GaiNianEnum.行业_3日排行.getCode(),GaiNianEnum.行业_3日排行.getUrl());
            updateHistortData(GaiNianEnum.概念_3日排行.getCode(),GaiNianEnum.概念_3日排行.getUrl());
            sendmailService.insertEvent(CommonUtils.TASK_NAME_RULE_4, CommonUtils.SUCCESS_MESSAGE,"SUCCESS",CommonUtils.RULE_SUCCESS);
        } catch (Exception e) {
            sendmailService.insertEvent(CommonUtils.TASK_NAME_RULE_4, CommonUtils.FAILE_MESSAGE + JSONObject.toJSONString(e),"ERROR",CommonUtils.RULE_EXCEPTION);
        }
    }

    private void updateHistortData(String type,String url) {
        // HttpClient 超时配置
        RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD)
                .setConnectionRequestTimeout(6000).setConnectTimeout(6000).build();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();
        try {
            Thread.sleep(1000);
            // 发送请求，并执行
            String htmlForStock = getHtmlStrByUrl(url, httpClient, COOKIE, USER_AGENT);
            // 网页内容解析
            log.info("该网页存在,正在解析:{}", htmlForStock);
            Document doc = Jsoup.parse(htmlForStock);
            // 获取table表的行集合元素
            Elements trs = doc.select("table[class=m-table J-ajax-table]").select("tr");
            //只统计前4板块的标记
            if(HOT_TAG_NUM<=4){
                HotTag hotTag=hotTagService.createHotTag();
                hot_tag_id=hotTag.getId();
            }
            //   doc
            for (int j = 1; j < 30; j++) {
                Elements tds = trs.get(j).select("td");
                GaiNianZiJingPaiHang info = new GaiNianZiJingPaiHang();
                info.setType(type);
                try {
                    //板块
                    String str = tds.get(1).html().split(">")[1];
                    info.setHanYe(str.split("<")[0]);
                    //URL
                    info.setUrl(tds.get(1).select("a").first().attr("href"));
                    //板块编码
                    String bankuaiCode = tds.get(1).html().split("/")[6];
                    info.setCode(bankuaiCode);
                    //公司家数
                    info.setCompanyNum(Integer.valueOf(tds.get(2).html()));
                    //行业指数
                    info.setHanYeZhiShu(new BigDecimal(tds.get(3).html()));
                    //阶段涨跌幅
                    info.setZhangDie(new BigDecimal(tds.get(4).html().replace("%", "")));
                    //流入资金(亿)
                    info.setZiJinLiuRu(new BigDecimal(tds.get(5).html()));
                    //流出资金(亿)
                    info.setZiJinLiuChu(new BigDecimal(tds.get(6).html()));
                    //
                    info.setJinLiuRu(new BigDecimal(tds.get(7).html()));
                    //
                    info.setCreateTime(new Date());
                    info.setModifyTime(new Date());
                    info.setDate(holidayService.getDayByNum(0));
                    GaiNianZiJingPaiHang param = new GaiNianZiJingPaiHang();
                    param.setCode(bankuaiCode);
                    param.setDate(info.getDate());
                    Map<String, Integer> map = new HashMap();
                    map.put("zhang", 0);
                    map.put("die", 0);
                    List<StockInfo> stockInfoList= Lists.newArrayList();
                    getRatio(info, 1, map,stockInfoList,getUrl(type));
                    GaiNianZiJingPaiHang record = gaiNianZiJingPaiHangMapper.selectOne(param);
                    if (null != record) {
                        log.info("历史记录存在！ code={}  行业={}", info.getCode(), info.getHanYe());
                        info.setId(record.getId());
                        info.setCreateTime(record.getCreateTime());
                        info.setModifyTime(new Date());
                        gaiNianZiJingPaiHangMapper.updateByPrimaryKey(info);
                    } else {
                        gaiNianZiJingPaiHangMapper.insert(info);
                    }
                    //TODO 监控昨日前三板块的成交量
                    log.info(" data={}", JSONObject.toJSONString(info));
                    //生成新的强势板块
                    qinXuGaoDuTask.initGaiNianBanKuai(stockInfoList,info.getHanYe(),info.getCode());
                } catch (Exception e) {
                    log.error("erro={}", e);
                }
                HOT_TAG_NUM++;
            }
        } catch (Exception e) {
            log.error("erro={}", e);
        }
    }

    private String getUrl(String type){
        if(GaiNianEnum.行业_1日排行.getCode().equals(type)) {
            return GaiNianEnum.行业_SUB_URL.getUrl();
        }
        if(GaiNianEnum.行业_3日排行.getCode().equals(type)) {
            return GaiNianEnum.行业_SUB_URL.getUrl();
        }
        if(GaiNianEnum.概念_1日排行.getCode().equals(type)) {
            return GaiNianEnum.概念_SUB_URL.getUrl();
        }
        if(GaiNianEnum.概念_3日排行.getCode().equals(type)) {
            return GaiNianEnum.概念_SUB_URL.getUrl();
        }
        if(GaiNianEnum.概念_5日排行.getCode().equals(type)) {
            return GaiNianEnum.概念_SUB_URL.getUrl();
        }
        return "";
    }


    /**
     * 计算涨跌比
     *
     * @param info
     */
    private  void getRatio(GaiNianZiJingPaiHang info, int page, Map<String, Integer> map, List<StockInfo> stockInfoList,String subUrl) throws Exception {
        Integer zhang = map.get("zhang");
        Integer die = map.get("die");
        RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD)
                .setConnectionRequestTimeout(6000).setConnectTimeout(6000).build();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();
        StringBuffer url = new StringBuffer(subUrl).append(page).append("/ajax/1/code/").append(info.getCode());
        Thread.sleep(1000);
        // 发送请求，并执行
        String htmlForStock = getHtmlStrByUrl(url.toString(), httpClient, COOKIE, USER_AGENT);
        // 网页内容解析
        log.info("该网页存在,正在解析:{}", htmlForStock);
        Document doc = Jsoup.parse(htmlForStock);
        // 获取table表的行集合元素
        Elements trs = doc.select("table[class=m-table m-pager-table]").select("tr");
        String elements = doc.getElementById("m-page").html();
        String result = "";
        int pageSize=0;
        try {

            Matcher regexMatcher = regex.matcher(elements);
            if (regexMatcher.find()) {
                result = regexMatcher.group().split(">")[1].split("<")[0].split("/")[1];
            }
            pageSize= Integer.valueOf(result);
        } catch (Exception ex) {
            log.info("error ={}", ex);
        }
        //   doc
        for (int j = 1; j <trs.size(); j++) {
            Elements tds = trs.get(j).select("td");
            try {
                String stockName=  tds.get(1).select("a").html();
                BigDecimal data = new BigDecimal(tds.get(4).html());
                if (data.compareTo(BigDecimal.ZERO) == 1) {
                    zhang++;
                } else {
                    die++;
                }
                //只统计前4板块的标记
                if(HOT_TAG_NUM<=4){
                    initTag(stockName,info,stockInfoList,data);
                }
            } catch (Exception e) {
                log.error(" 读取个股数据error  data={} ", tds.get(4).html());
            }
        }
        map.put("zhang", zhang);
        map.put("die", die);
        info.setZhang(zhang);
        info.setDie(die);
        info.setRatio(new BigDecimal(zhang).divide(new BigDecimal(zhang+die), 4, BigDecimal.ROUND_HALF_UP));
        if (page < pageSize) {
            page++;
            getRatio(info, page, map,stockInfoList,subUrl);
        }
    }

    private void initTag(String stockName,GaiNianZiJingPaiHang info, List<StockInfo> stockInfoList,BigDecimal zhangDie){
        try {
            CompanyCodeInfo companyCodeInfo= companyCodeInfoService.getInfoByStockName(stockName);
            if(null==companyCodeInfo){
                return;
            }
            StockInfo stockInfo=new StockInfo();
            stockInfo.setCode(companyCodeInfo.getCompanyCode());
            stockInfo.setZhangdie(null==zhangDie?BigDecimal.ZERO:zhangDie);
            stockInfoList.add(stockInfo);
            hotTagService.inserStockTag(hot_tag_id.longValue(),companyCodeInfo.getId(),info);
        }catch (Exception e){
            log.error("生成Tag 失败 error={}",e);
        }
    }




    public static String getHtmlStrByUrl(String url, CloseableHttpClient httpClient, String COOKIE, String USER_AGENT) throws Exception {
        HttpGet httpGetForFName = new HttpGet(url);
        httpGetForFName.addHeader("User-Agent", USER_AGENT);
        httpGetForFName.addHeader("Cookie", getCOOKIE());
        httpGetForFName.addHeader("Content-Type", "text/html; charset=gbk");
        httpGetForFName.addHeader("Accept-Encoding", "gzip, deflate");
        httpGetForFName.addHeader("Connection", "keep-alive");

        // 发送请求，并执行
        CloseableHttpResponse response;
        String html = "";
        try {
            response = httpClient.execute(httpGetForFName);
            // response植入cookie
            Header[] ssoResponseHeader = response.getHeaders("Set-Cookie");
            InputStream in = response.getEntity().getContent();
            html = convertStreamToString(in);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return html;
    }

    /**
     *
     * @param url
     * @param httpClient
     * @param COOKIE
     * @param USER_AGENT
     * @return
     * @throws Exception
     */
    public static String getHtmlStrByUrlDfcf(String url, CloseableHttpClient httpClient, String COOKIE, String USER_AGENT) throws Exception {
        HttpGet httpGetForFName = new HttpGet(url);
        // httpGetForFName.addHeader("User-Agent", USER_AGENT);
        // httpGetForFName.addHeader("Cookie", getCOOKIE());
        httpGetForFName.addHeader("Content-Type", "text/html; charset=utf-8");
        httpGetForFName.addHeader("Accept-Encoding", "gzip, deflate");
        httpGetForFName.addHeader("Connection", "keep-alive");
//        httpGetForFName.addHeader("Referer", "https://q.10jqka.com.cn/");
//        httpGetForFName.addHeader("Host", "q.10jqka.com.cn");

        // 发送请求，并执行
        CloseableHttpResponse response;
        String html = "";
        try {
            response = httpClient.execute(httpGetForFName);
            // response植入cookie
            Header[] ssoResponseHeader = response.getHeaders("Set-Cookie");
            InputStream in = response.getEntity().getContent();
            html = convertStreamToString(in);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return html;
    }

    public static String convertStreamToString(InputStream in) {
        StringBuilder sb = new StringBuilder();
        try {

            InputStreamReader isr = new InputStreamReader(in, "gbk");
            BufferedReader reader = new BufferedReader(isr);
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "/n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();

    }

    private static String getCOOKIE() throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
       // String jsFileName = GaiNianZiJingPaiHangTask.class.getClassLoader().getResource("static/js/aes.min.js").getFile(); // 读取js文件
        // FileReader reader = new FileReader(); // 执行指定脚本
        //spring boot 不能直接这样读取路径，jar包中会报错
        ClassPathResource classPathResource = new ClassPathResource("static/js/aes.min.js");
        InputStreamReader  reader=   new InputStreamReader(classPathResource.getInputStream());
        engine.eval(reader);
        if (engine instanceof Invocable) {
            Invocable invoke = (Invocable) engine; // 调用merge方法，并传入两个参数
            // c = merge(2, 3);
            String c = (String) invoke.invokeFunction("v");
            COOKIE = "v=" + c;
        }
        reader.close();
        return COOKIE;
    }

    public static void main(String[] args) {
        String path=GaiNianZiJingPaiHangTask.class.getClassLoader().getResource("static/js/aes.min.js").getFile();
        System.out.println(path);
    }
}
